package com.huc.netty.codec;

import com.huc.netty.constants.ReqType;
import com.huc.netty.constants.RpcConstant;
import com.huc.netty.core.Header;
import com.huc.netty.core.RpcProtocol;
import com.huc.netty.core.RpcRequest;
import com.huc.netty.core.RpcResponse;
import com.huc.netty.serial.ISerializer;
import com.huc.netty.serial.SerializerManager;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @author huc
 * @version 1.0
 * @note 解码器
 * @date 2021/9/16 9:51
 */
@Slf4j
public class RpcDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        log.info("========开始解码==========");

        if (byteBuf.readableBytes() < RpcConstant.HEAD_TOTOAL_LEN) {
            return;
        }
        byteBuf.markReaderIndex(); //标记读取开始索引
        short maci = byteBuf.readShort(); //读取2个字节的magic
        if (maci != RpcConstant.MAGIC) {
            throw new IllegalArgumentException("Illegal request parameter 'magic'," + maci);
        }

        byte serialType = byteBuf.readByte(); //读取一个字节的序列化类型
        byte reqType = byteBuf.readByte(); //读取一个字节的消息类型
        long requestId = byteBuf.readLong(); //读取请求id
        int dataLength = byteBuf.readInt(); //读取数据报文长度

        if (byteBuf.readableBytes() < dataLength) {
            byteBuf.resetReaderIndex();
            return;
        }
        //读取消息体的内容
        byte[] content = new byte[dataLength];
        byteBuf.readBytes(content);

        Header header = new Header(maci, serialType, reqType, requestId, dataLength);
        ISerializer serializer = SerializerManager.getSerializer(serialType);
        ReqType rt = ReqType.findByCode(reqType);
        switch (rt) {
            case REQUEST:
                RpcRequest request = serializer.deserialize(content, RpcRequest.class);
                RpcProtocol<RpcRequest> reqProtocol = new RpcProtocol<>();
                reqProtocol.setHeader(header);
                reqProtocol.setContent(request);
                list.add(reqProtocol);
                break;
            case RESPONSE:
                RpcResponse response = serializer.deserialize(content, RpcResponse.class);
                RpcProtocol<RpcResponse> resProtocol = new RpcProtocol<>();
                resProtocol.setHeader(header);
                resProtocol.setContent(response);
                list.add(resProtocol);
                break;
            case HEARTBEAT:
                //TODO 心跳处理
                break;
            default:
                break;
        }
        log.info("========解码完成==========");
    }


}
